/**
 * reCaptcha add-on
 * This add-ons shows and validates a Google reCAPTCHA v2
 *
 * @link        http://formvalidation.io/addons/reCaptcha2/
 * @author      https://twitter.com/nghuuphuoc
 * @copyright   (c) 2013 - 2015 Nguyen Huu Phuoc
 * @license     http://formvalidation.io/license/
 */
/* global grecaptcha: false */
(function($) {
    FormValidation.AddOn.reCaptcha2 = {
        html5Attributes: {
            element: 'element',
            message: 'message',
            sitekey: 'siteKey',
            theme: 'theme',
            timeout: 'timeout'
        },

        // The captcha field name, generated by Google reCAPTCHA
        CAPTCHA_FIELD: 'g-recaptcha-response',

        // The default session timeout (in seconds)
        CAPTCHA_TIMEOUT: 2 * 60,

        /**
         * @param {FormValidation.Base} validator The validator instance
         * @param {Object} options The add-on options. Consists of the following keys:
         * - element: The ID of element showing the captcha
         * - theme: The theme name provided by Google. It can be light (default), dark
         * - siteKey: The site key provided by Google
         * - message: The invalid message that will be shown in case the captcha is not valid
         * You don't need to define it if the back-end URL above returns the message
         * - timeout: The number of seconds that session will expire
         */
        init: function(validator, options) {
            var that = this;
            window.reCaptchaLoaded = function() {
                // Render the captcha
                grecaptcha.render(options.element, {
                    sitekey: options.siteKey,
                    theme: options.theme || 'light',
                    callback: function(response) {
                        validator.updateStatus(that.CAPTCHA_FIELD, validator.STATUS_VALID);

                        // We might need to update the captcha status when session expires
                        setTimeout(function() {
                            validator.updateStatus(that.CAPTCHA_FIELD, validator.STATUS_INVALID);
                        }, (options.timeout || that.CAPTCHA_TIMEOUT) * 1000);
                    }
                });

                setTimeout(function() {
                    that._addCaptcha(validator, options);
                }, 3000);
            };

            var script = document.createElement('script');
            script.type  = 'text/javascript';
            script.async = true;
            script.defer = true;
            script.src   = '//www.google.com/recaptcha/api.js?onload=reCaptchaLoaded&render=explicit';
            document.getElementsByTagName('body')[0].appendChild(script);
        },

        _addCaptcha: function(validator, options) {
            var that = this;

            validator
                .getForm()
                // Add new field after loading captcha
                .formValidation('addField', that.CAPTCHA_FIELD, {
                    excluded: false,
                    validators: {
                        callback: {
                            message: options.message,
                            callback: function(value, validator, $field) {
                                return (value !== '');
                            }
                        }
                    }
                });
        }
    };
}(jQuery));
